//********************************************************************************************************************//
//ORGANIZATION:
//AUTHOR: bpeng(bogers.peng@gmail.com)
//SUMMARY:
//********************************************************************************************************************//
#ifndef NATIVE_SYSTEM_BASE_OBJECT_H
#define NATIVE_SYSTEM_BASE_OBJECT_H

#ifndef NATIVE_SYSTEM_BASE_ATOM_H
#include "System/Base/Atom.h"
#endif

#define NATIVE_DECLARE_CONST_OBJECT(CLASS, CONST_CLASS) \
class CLASS; typedef const CLASS CONST_CLASS;

namespace Native { namespace System
{
    //****************************************************************************************************************//
    //CObject
    //
    //****************************************************************************************************************//
    NATIVE_DECLARE_CONST_OBJECT(CObject, C_OBJECT);
    class NATIVE_LIBRARY_EXPORT CObject
    {
    public:
        CObject();
        CObject(C_OBJECT& that);
        CObject(C_OBJECT&& that);

    public:
        //Get type name i.e. this class name.
        //This virtual function should be overrided by its derivative class
        virtual wstring TypeName() const;
        
        //Convert class to a meaningful WSTRING
        virtual wstring ToString() const;

        virtual size_t Hash() const;

        virtual bool AnalogousTo(C_OBJECT& rvalue) const;

    private:
        virtual void _Finalize();
    };
}}
//********************************************************************************************************************//
//Macros
//********************************************************************************************************************//

//Return needed type name i.e. object`s simplified name by inputing its pPointer.
#define NATIVE_OBJECT_TYPE_NAME \
    UString::ToWideString(typeid(*this).name())

#define NATIVE_OBJECT_HASH \
    typeid(*this).hash_code();

//Declare uniform object definition on .h file.
//Every derivative classes must use this macro.
#define NATIVE_DECLARE_OBJECT \
    public:virtual wstring TypeName() const{return move(NATIVE_OBJECT_TYPE_NAME);}

#define NATIVE_DECLARE_PROPERTY(GET_ACCESS, SET_ACCESS, TYPE_NAME, METHOD_NAME, MEMBER_NAME) \
    protected:TYPE_NAME MEMBER_NAME;\
GET_ACCESS:TYPE_NAME METHOD_NAME() const {return MEMBER_NAME;}; \
SET_ACCESS:void METHOD_NAME(const TYPE_NAME& value){MEMBER_NAME = value;};

#endif
